package com.liy.cloud.base.service.impl;

import com.liy.cloud.auth.client.utils.RequestUtil;
import com.liy.cloud.base.entity.BaseEquTypeEntity;
import com.liy.cloud.base.entity.BaseLineEntity;
import com.liy.cloud.base.service.BaseEquTypeService;
import com.liy.cloud.base.service.BaseLineService;
import com.liy.cloud.base.service.StationDeviceTreeService;
import com.liy.cloud.common.base.entity.BaseEquInfoEntity;
import com.liy.cloud.common.base.entity.BaseStationEntity;
import com.liy.cloud.common.base.service.BaseEquInfoService;
import com.liy.cloud.common.base.service.BaseStationService;
import com.liy.cloud.common.feign.api.SysFeignClient;
import com.das.framework.common.utils.Tools;
import com.das.framework.common.vo.PageVO;
import com.das.framework.common.web.extcall.RestTemplateUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;

/**
 * 车站-设备树服务实现
 * @author libs
 * @ClassName StationDeviceTreeServiceImpl
 * @Description
 * @date 2018/11/21 08:43:39
 */
@Service
public class StationDeviceTreeServiceImpl implements StationDeviceTreeService {

    @Autowired
    private BaseLineService baseLineService;

    @Autowired
    private BaseStationService baseStationService;

    @Autowired
    private BaseEquInfoService baseEquInfoService;

    @Autowired
    private BaseEquTypeService baseEquTypeService;

    @Autowired
    private RestTemplateUtil restTemplateUtil;
    @Autowired
    private SysFeignClient sysFeignClient;

    /*
     * 树中的节点层次顺序
     */
    private static final String[] LEVELS = {"line", "station", "type", "deviceType", "device"};

    /*
     * 叶子节点类型，SC 的默认叶子节点为 device：设备，CLC 的默认叶子节点为 station：站点
     * 可选值：line：线路，station：站点，type：设备大类，deviceType：设备种类，device：设备
     */
    private String leaf;

    /*
     * 是否显示没有子节点的非叶子节点
     */
    private boolean showNoChildren;

    /*
     * 显示的节点集合
     */
    private List<String> show;

    @Override
    public List<Map<String, Object>> getStationDeviceTree(Map<String, Object> params) throws Exception {

        showNoChildren = (boolean) params.get("showNoChildren");
        String stationType = (String) params.get("stationType");
        String rootName = (String) params.get("rootName");
        List<Map<String, Object>> stationDeviceTree = new LinkedList<>();
        Map<String, Object> root = new LinkedHashMap<>();
        stationDeviceTree.add(root);
        root.put("id", "root");
        root.put("key", "root");
        root.put("label", rootName);
        root.put("type", "root");
        root.put("leaf", false);
        List<Map<String, Object>> children = new LinkedList<>();
        root.put("children", children);

        if("CLC".equalsIgnoreCase(stationType)){
            show = (List<String>) params.get("clcShow");
            leaf = getLeaf("station");
            if(Tools.StringIsNullOrSpace(rootName)){
                root.put("label", "CLC");
            }
            // 只加载需要显示的子节点
            if(show.contains("line")){
                lineToTree(children, null, root.get("key"));
            } else if(show.contains("station")) {
                stationToTree(children, null, root.get("key"));
            } else {
                loadDeviceTree(children, null, root.get("key"));
            }
        } else if("SC".equalsIgnoreCase(stationType)) {
            show = (List<String>) params.get("scShow");
            leaf = getLeaf("device");
            String stationId = (String) params.get("stationId");
            BaseStationEntity station = baseStationService.findById(stationId);
            if(Tools.StringIsNullOrSpace(rootName)){
                root.put("label", station.getNameCn());
            }
            // 设备查询条件
            BaseEquInfoEntity equInfoQuery = new BaseEquInfoEntity();
            equInfoQuery.setStationid(stationId);
            // 只加载需要显示的子节点
            loadDeviceTree(children, equInfoQuery, root.get("key"));
        }
        return stationDeviceTree;
    }

    /**
     * 加载设备树
     *
     * @param list
     * @param equInfoQuery
     * @param superKey 上级 key
     * @return 
     * @auther libs
     * @date 2018/11/21 16:59
     */
    private void loadDeviceTree(List<Map<String, Object>> list, BaseEquInfoEntity equInfoQuery, Object superKey) throws Exception {
        if(show.contains("type")){
            typeToTree(list, equInfoQuery, superKey);
        } else if(show.contains("deviceType")){
            deviceTypeToTree(list, null, equInfoQuery, superKey);
        } else if(show.contains("device")){
            deviceToTree(list, equInfoQuery, superKey);
        }
    }

    /**
     * 获取叶子节点类型，必须在 show 初始化完成之后调用
     *
     * @param defaultType 默认值
     * @return 
     * @auther libs
     * @date 2018/11/21 14:40
     */
    private String getLeaf(String defaultType) {
        if(show != null && !show.isEmpty()){
            // 从最深的节点开始查找，找到第一个 show 中包含的类型则为叶子节点类型
            for (int i = LEVELS.length - 1; i >=0; i--) {
                if(show.contains(LEVELS[i])){
                    return  LEVELS[i];
                }
            }
        }
        return defaultType;
    }

    /**
     * 查询线路信息及子节点，并加入到树中
     *
     * @param list
     * @param lineEntity 查询条件
     * @param superKey 上级 key
     * @return
     * @auther libs
     * @date 2018/11/20 9:46
     */
    private void lineToTree(List<Map<String, Object>> list, BaseLineEntity lineEntity, Object superKey) throws Exception {
        List<BaseLineEntity> lineList = baseLineService.findList(lineEntity);
        for (BaseLineEntity line : lineList) {
            Map<String, Object> map = new LinkedHashMap<>();
            map.put("id", line.getId());
            map.put("key", superKey + "_" + line.getId());
            map.put("label", line.getNameCn());
            map.put("type", "line");
            // 如果不是叶子节点则继续加载节点
            if(!"line".equals(leaf)){
                map.put("leaf", false);
                List<Map<String, Object>> children = new LinkedList<>();
                map.put("children", children);
                BaseEquInfoEntity equInfoQuery = new BaseEquInfoEntity();
                equInfoQuery.setLineId(line.getId());
                // 只加载需要显示的子节点
                if(show.contains("station")){
                    BaseStationEntity stationEntity = new BaseStationEntity();
                    stationEntity.setLineId(line.getId());
                    stationToTree(children, stationEntity, map.get("key"));
                } else {
                    loadDeviceTree(children, equInfoQuery, map.get("key"));
                }
                if(!children.isEmpty() || showNoChildren){
                    list.add(map);
                }
            } else {
                map.put("leaf", true);
                list.add(map);
            }
        }
    }

    /**
     * 查询车站信息及子节点，并加入到树信息中
     *
     * @param list 树节点列表
     * @param stationEntity 查询条件
     * @param superKey 上级 key
     * @return
     * @auther libs
     * @date 2018/11/12 14:29
     */
    private void stationToTree(List<Map<String, Object>> list, BaseStationEntity stationEntity, Object superKey) throws Exception {
        List<BaseStationEntity> stationList = baseStationService.findList(stationEntity);
        for (BaseStationEntity station : stationList) {
            Map<String, Object> map = new LinkedHashMap<>();
            map.put("id", station.getId());
            map.put("key", superKey + "_" + station.getId());
            map.put("label", station.getNameCn());
            map.put("type", "station");
            // 如果不是叶子节点则继续加载节点
            if(!"station".equals(leaf)){
                map.put("leaf", false);
                List<Map<String, Object>> children = new LinkedList<>();
                map.put("children", children);
                // 设备查询条件
                BaseEquInfoEntity equInfoQuery = new BaseEquInfoEntity();
                equInfoQuery.setStationid(station.getId());
                // 只加载需要显示的子节点
                loadDeviceTree(children, equInfoQuery, map.get("key"));
                if(!children.isEmpty() || showNoChildren){
                    list.add(map);
                }
            } else {
                map.put("leaf", true);
                list.add(map);
            }
        }
    }

    /**
     * 查询设备大类及子节点，并加入到树信息中
     *
     * @param list 树节点列表
     * @param equInfo 查询条件
     * @param superKey 上级 key
     * @return
     * @auther libs
     * @date 2018/11/19 14:31
     */
    private void typeToTree(List<Map<String, Object>> list, BaseEquInfoEntity equInfo, Object superKey) throws Exception {
//        String url = restTemplateUtil.getSysServerUrl() + "/dict/item/enablelist";
//        Map<String, Object> params = new HashMap<>();
//        params.put("typeCode", "01");
//        PageVO<Map<String, String>> pageVO = restTemplateUtil.get(url, params, PageVO.class);
        Map<String, Object> params = new HashMap<>();
        params.put("typeCode", "01");
        PageVO pageVO = sysFeignClient.getDictItemEnableList(RequestUtil.map2urlparam(params),1000, 1);
        if(!Tools.listIsNullOrEmpty(pageVO.getResults())){
            List<Map<String, String>> results = (List<Map<String, String>>) pageVO.getResults();
            for (Map<String, String> result : results) {
                Map<String, Object> map = new LinkedHashMap<>();
                map.put("id", result.get("itemCode"));
                map.put("key", superKey + "_" + result.get("itemCode"));
                map.put("label", result.get("itemName"));
                map.put("type", "type");
                // 如果不是叶子节点则继续加载节点
                if (!"type".equals(leaf)) {
                    map.put("leaf", false);
                    List<Map<String, Object>> children = new LinkedList<>();
                    map.put("children", children);
                    // 只加载需要显示的子节点
                    if (show.contains("deviceType")) {
                        BaseEquTypeEntity equTypeQuery = new BaseEquTypeEntity();
                        equTypeQuery.setTypeCode(result.get("itemCode"));
                        deviceTypeToTree(children, equTypeQuery, equInfo, map.get("key"));
                    } else if (show.contains("device")) {
                        if (equInfo == null) {
                            equInfo = new BaseEquInfoEntity();
                        }
                        equInfo.setTypeCode(result.get("itemCode"));
                        deviceToTree(children, equInfo, map.get("key"));
                    }
                    if (!children.isEmpty() || showNoChildren) {
                        list.add(map);
                    }
                } else {
                    map.put("leaf", true);
                    list.add(map);
                }
            }
        }
    }

    /**
     * 查询设备种类及子节点，并加入到树信息中
     *
     * @param list 树节点列表
     * @param equType 查询条件
     * @param equInfo 查询条件
     * @param superKey 上级 key
     * @return
     * @auther libs
     * @date 2018/11/19 14:31
     */
    private void deviceTypeToTree(List<Map<String, Object>> list, BaseEquTypeEntity equType, BaseEquInfoEntity equInfo, Object superKey) throws Exception {
        List<BaseEquTypeEntity> equTypeList = baseEquTypeService.findList(equType);
        for (BaseEquTypeEntity type : equTypeList) {
            Map<String, Object> map = new LinkedHashMap<>();
            map.put("id", type.getId());
            map.put("key", superKey + "_" + type.getId());
            map.put("label", type.getName());
            map.put("type", "deviceType");
            // 如果不是叶子节点则继续加载节点
            if(!"deviceType".equals(leaf)){
                map.put("leaf", false);
                List<Map<String, Object>> children = new LinkedList<>();
                map.put("children", children);
                // 只加载需要显示的子节点
                if(show.contains("device")){
                    if(equInfo == null){
                        equInfo = new BaseEquInfoEntity();
                    }
                    equInfo.setDevicetype(type.getId());
                    deviceToTree(children, equInfo, map.get("key"));
                }
                if(!children.isEmpty() || showNoChildren){
                    list.add(map);
                }
            } else {
                map.put("leaf", true);
                list.add(map);
            }
        }
    }

    /**
     * 查询设备信息，并加入到树信息中
     *
     * @param list 树节点列表
     * @param equInfo 查询条件
     * @param superKey 上级 key
     * @return
     * @auther libs
     * @date 2018/11/19 14:16
     */
    private void deviceToTree(List<Map<String, Object>> list, BaseEquInfoEntity equInfo, Object superKey) throws Exception {
        List<BaseEquInfoEntity> equInfoList = baseEquInfoService.findList(equInfo);
        for (BaseEquInfoEntity equ : equInfoList) {
            Map<String, Object> map = new LinkedHashMap<>();
            list.add(map);
            map.put("id", equ.getId());
            map.put("key", superKey + "_" + equ.getId());
            map.put("label", equ.getDevicename());
            map.put("type", "device");
            map.put("leaf", true);
        }
    }
}
